﻿using ComTools.Encrypt;
using MSSQL.CommandTool;
using MSSQL.PagingCorrelation;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;


namespace MSSQL.Interface
{
    /// <summary>
    /// 该类对接口进行了默认的实现，并定义了实际实现的抽象方法
    /// </summary>
    public abstract class AbstractDataQuery : IDataQuery
    {
        /// <summary>
        /// 数据库名字
        /// </summary>
        public string DataBaseName
        {
            set
            {
                try
                {
                    DatabaseInstance instance = DatabaseManager.GetDatabase(value);
                    connectionString = bool.Parse(instance.IsEncryption) ? AESEncryptHelper.Decrypt(instance.ConnectionString) : instance.ConnectionString;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 链接字符串，从工具中读取配置
        /// </summary>
        private string connectionString = string.Empty;

        /// <summary>
        /// 获取连接
        /// </summary>
        /// <returns>打开的链接，如果失败返回的是null</returns>
        private IDbConnection GetConnection()
        {
            try
            {
                if (string.IsNullOrEmpty(connectionString)) return null;

                IDbConnection connection = null;

                connection = new SqlConnection(connectionString);

                connection.Open();

                return connection;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        /// <param name="connection">数据库连接</param>
        private void CloseConnection(IDbConnection connection)
        {
            try
            {
                if (connection != null && connection.State == ConnectionState.Open)
                {
                    connection.Close();
                    connection.Dispose();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 单条查询，传递SQL语句与条件
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="sqlCommand">SQL命令</param>
        /// <param name="parameter">参数</param>
        /// <returns>查询结果</returns>
        public T QuerySingleData<T>(string sqlCommand, object parameter)
        {
            IDbConnection connection = null;
            try
            {
                connection = GetConnection();
                if (connection == null) throw new ApplicationException("获取数据库连接失败");
                return QuerySingleDataImpl<T>(connection, sqlCommand, parameter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                CloseConnection(connection);
            }
        }


        /// <summary>
        /// 单条查询，传递唯一标识符
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="gCode">唯一编码</param>
        /// <returns>查询结果</returns>
        public T QuerySingleByCode<T>(string gCode)
        {

            IDbConnection connection = null;
            try
            {
                connection = GetConnection();
                if (connection == null) throw new ApplicationException("获取数据库连接失败");
                return QuerySingleByCodeImpl<T>(connection, gCode);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                CloseConnection(connection);
            }
        }

        /// <summary>
        /// 单条查询,传递条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public T QuerySingleByWhere<T>(string sWhere,object parameter)
        {

            IDbConnection connection = null;
            try
            {
                connection = GetConnection();
                if (connection == null) throw new ApplicationException("获取数据库连接失败");
                return QuerySingleByWhereImpl<T>(connection, sWhere,parameter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                CloseConnection(connection);
            }
        }

        /// <summary>
        /// 查询多条数据
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="sqlCommand">SQL命令</param>
        /// <param name="parameter">参数</param>
        /// <returns>查询结果</returns>
        public IList<T> QueryListData<T>(string sqlCommand, object parameter)
        {
            IDbConnection connection = null;

            try
            {
                connection = GetConnection();
                if (connection == null) throw new ApplicationException("获取数据库连接失败");
                return QueryListDataImpl<T>(connection, sqlCommand, parameter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                CloseConnection(connection);
            }
        }

        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <typeparam name="T">查询结果的类型</typeparam>
        /// <param name="pageInfo">分页条件</param>
        /// <param name="sqlCommand">sql语句</param>
        /// <param name="parameter">参数</param>
        /// <returns>分页结果对象</returns>
        public PagingResult<T> QueryPaginationData<T>(PageInfo pageInfo, string sqlCommand, object parameter)
        {
            IDbConnection connection = null;

            try
            {
                connection = GetConnection();
                if (connection == null) throw new ApplicationException("获取数据库连接失败");
                return QueryPaginationDataImpl<T>(connection, pageInfo, sqlCommand, parameter);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                CloseConnection(connection);
            }
        }


        /// <summary>
        /// 需要实现的单条查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="gCode"></param>
        /// <returns></returns>
        public abstract T QuerySingleByCodeImpl<T>(IDbConnection connection, string gCode);


        /// <summary>
        /// 需要实现的单条查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="sWhere"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public abstract T QuerySingleByWhereImpl<T>(IDbConnection connection, string sWhere, object parameter = null);

        /// <summary>
        /// 需要实现的单条查询
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="connection">连接对象</param>
        /// <param name="sqlCommand">SQL命令</param>
        /// <param name="param">参数</param>
        /// <returns>查询结果</returns>
        public abstract T QuerySingleDataImpl<T>(IDbConnection connection, string sqlCommand, object parameter);

        /// <summary>
        /// 需要实现的查询多条数据方法
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="connection">连接对象</param>
        /// <param name="sqlCommand">SQL命令</param>
        /// <param name="parameter">参数</param>
        /// <returns>查询结果</returns>
        public abstract IList<T> QueryListDataImpl<T>(IDbConnection connection, string sqlCommand, object parameter);

        /// <summary>
        /// 需要实现的实际分页查询的方法
        /// </summary>
        /// <typeparam name="T">查询的实体类型</typeparam>
        /// <param name="connection">连接对象</param>
        /// <param name="pageInfo">查询分页条件</param>
        /// <param name="sqlCommand">SQL命令</param>
        /// <param name="parameter">参数</param>
        /// <returns>查询结果</returns>
        public abstract PagingResult<T> QueryPaginationDataImpl<T>(IDbConnection connection, PageInfo pageInfo, string sqlCommand, object parameter);
    }
}
